﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Concurrent;
using System.Collections.Specialized;
using System.Threading;

namespace FileSystemAudit
{
    public delegate void NotifyFolderAnalyzerAddedEventHandler(FolderAnalyzer source, NotifyCollectionChangedEventArgs e);

    public class FolderAnalyzerMonitoredCollection : BlockingCollection<FolderAnalyzer>
    {
        public event NotifyFolderAnalyzerAddedEventHandler OnFolderAnalyzerAdded;

        private System.Collections.Concurrent.ConcurrentQueue<FolderAnalyzer> queue = new ConcurrentQueue<FolderAnalyzer>();
        public new void Add(FolderAnalyzer item)
        {
            base.Add(item);
            if (OnFolderAnalyzerAdded != null)
                OnFolderAnalyzerAdded.Invoke(item, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
            else
                queue.Enqueue(item);
        }

        public new bool TryAdd(FolderAnalyzer item)
        {
            bool res = false;
            if (base.TryAdd(item))
            {
                if (OnFolderAnalyzerAdded != null)
                    OnFolderAnalyzerAdded.Invoke(item, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
                else
                    queue.Enqueue(item);
            }
            return res;
        }
        public new bool TryAdd(FolderAnalyzer item, int millisecondsTimeout)
        {
            bool res = false;
            if (base.TryAdd(item, millisecondsTimeout))
            {
                if (OnFolderAnalyzerAdded != null)
                    OnFolderAnalyzerAdded.Invoke(item, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
                else
                    queue.Enqueue(item);
            }
            return res;
        }

        public bool TryAdd(FolderAnalyzer item, int millisecondsTimeout, CancellationToken cancellationToken)
        {
            bool res = false;
            if (base.TryAdd(item, millisecondsTimeout, cancellationToken))
            {
                if (OnFolderAnalyzerAdded != null)
                    OnFolderAnalyzerAdded.Invoke(item, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
                else
                    queue.Enqueue(item);
            }
            return res;
        }

        public void TardiveEvent()
        {
            if (OnFolderAnalyzerAdded != null)
                while (queue.Count > 0)
                {
                    FolderAnalyzer item;
                    if (queue.TryDequeue(out item))
                    {
                        NotifyCollectionChangedEventArgs args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add);
                        OnFolderAnalyzerAdded.Invoke(item, args);
                    }
                }
        }

        public new bool TryTake(out FolderAnalyzer item, int millisecondsTimeout)
        {
            return base.TryTake(out item, millisecondsTimeout);
        }

    }
}
